package com.hk.webapp.custom;

import com.hk.webapp.bo.UserBo;
import lombok.Getter;
import lombok.Setter;
import org.apache.commons.lang3.StringUtils;
import org.springframework.http.ContentDisposition;
import org.springframework.lang.Nullable;
import org.springframework.util.FileCopyUtils;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.multipart.MultipartException;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.support.StandardMultipartHttpServletRequest;

import javax.mail.internet.MimeUtility;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.Part;
import java.io.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.*;

/**
 * (C) Copyright 2017-2019
 * All rights reserved.
 * <p>
 * 自定义多媒体请求实体
 *
 * @author DreamerCK
 * @date 2019-05-21 1:05
 **/
@SuppressWarnings("all")
public class CustomMultipartHttpServletRequest extends StandardMultipartHttpServletRequest {

    private static final String USER_ID = "userId";
    private static final String USERNAME = "username";

    @Setter
    private String username;
    @Setter
    @Getter
    private String userId;

    @Nullable
    private Set<String> multipartParameterNames;

    public CustomMultipartHttpServletRequest(HttpServletRequest request) throws MultipartException {
        this(request, false);
    }

    public CustomMultipartHttpServletRequest(HttpServletRequest request, UserBo userBo) throws MultipartException {
        this(request, false);
        this.userId = userBo.getUserId().toString();
        this.username = userBo.getUsername();
    }

    public CustomMultipartHttpServletRequest(HttpServletRequest request, boolean lazyParsing) throws MultipartException {
        super(request);
        if (!lazyParsing) {
            this.parseRequest(request);
        }

    }

    private void parseRequest(HttpServletRequest request) {
        try {
            Collection<Part> parts = request.getParts();
            this.multipartParameterNames = new LinkedHashSet(parts.size());
            MultiValueMap<String, MultipartFile> files = new LinkedMultiValueMap(parts.size());
            Iterator var4 = parts.iterator();

            while (var4.hasNext()) {
                Part part = (Part) var4.next();
                String headerValue = part.getHeader("Content-Disposition");
                ContentDisposition disposition = ContentDisposition.parse(headerValue);
                String filename = disposition.getFilename();
                if (filename != null) {
                    if (filename.startsWith("=?") && filename.endsWith("?=")) {
                        filename = CustomMultipartHttpServletRequest.MimeDelegate.decode(filename);
                    }

                    files.add(part.getName(), new CustomMultipartHttpServletRequest.StandardMultipartFile(part, filename));
                } else {
                    this.multipartParameterNames.add(part.getName());
                }
            }

            this.setMultipartFiles(files);
        } catch (Throwable var9) {
            this.handleParseFailure(var9);
        }

    }

    @Override
    public Enumeration<String> getHeaders(String name) {
        if (StringUtils.isNotBlank(name)) {
            if (name.equals(USERNAME)) {
                return Collections.enumeration(Collections.singletonList(username));
            } else if (name.equals(USER_ID)) {
                return Collections.enumeration(Collections.singletonList(userId));
            }
        }
        return super.getHeaders(name);
    }

    private static class MimeDelegate {
        private MimeDelegate() {
        }

        public static String decode(String value) {
            try {
                return MimeUtility.decodeText(value);
            } catch (UnsupportedEncodingException var2) {
                throw new IllegalStateException(var2);
            }
        }
    }

    private static class StandardMultipartFile implements MultipartFile, Serializable {
        private final Part part;
        private final String filename;

        public StandardMultipartFile(Part part, String filename) {
            this.part = part;
            this.filename = filename;
        }

        @Override
        public String getName() {
            return this.part.getName();
        }

        @Override
        public String getOriginalFilename() {
            return this.filename;
        }

        @Override
        public String getContentType() {
            return this.part.getContentType();
        }

        @Override
        public boolean isEmpty() {
            return this.part.getSize() == 0L;
        }

        @Override
        public long getSize() {
            return this.part.getSize();
        }

        @Override
        public byte[] getBytes() throws IOException {
            return FileCopyUtils.copyToByteArray(this.part.getInputStream());
        }

        @Override
        public InputStream getInputStream() throws IOException {
            return this.part.getInputStream();
        }

        @Override
        public void transferTo(File dest) throws IOException, IllegalStateException {
            this.part.write(dest.getPath());
            if (dest.isAbsolute() && !dest.exists()) {
                FileCopyUtils.copy(this.part.getInputStream(), Files.newOutputStream(dest.toPath()));
            }

        }

        @Override
        public void transferTo(Path dest) throws IOException, IllegalStateException {
            FileCopyUtils.copy(this.part.getInputStream(), Files.newOutputStream(dest));
        }
    }
}
